home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
(A)U
/
(A)U5.ADF
/
Virus_Checker
/
Virus_Checker.ARP.asm
< prev
next >
Wrap
Assembly Source File
|
1988-08-11
|
22KB
|
712 lines
**** Virus Checker ***
*** Checks for SCA virus, Byte Bandit Virus and Non-Standard Boot Blocks **
*** Based on the idea and code from Steve Tibbett on Fish #136 **
** Only this is much smaller and done in assembly language **
** Please send me any more viruses so I can update this **
** John Veldthuis
** 21 Ngatai Street
** Manaia, Taranaki
** New Zealand
** Placed in the Public domain libraries to help all get rid of Viruses **
include "exec/types.i"
include "libraries/arpbase.i"
include "intuition/intuition.i"
include "devices/trackdisk.i"
include "exec/memory.i"
xref _LVOOpenLibrary
xref _LVOCloseLibrary
xref _LVOFindTask
xref _LVOSetTaskPri
xref _LVODoIO
xref _LVOOpenDevice
xref _LVOCloseDevice
xref _LVOOpenWindow
xref _LVOCloseWindow
xref _LVOSetAPen
xref _LVOSetBPen
xref _LVOSetDrMd
xref _LVOSetWindowTitles
xref _LVORawDoFmt
xref _LVOWait
xref _LVOGetMsg
xref _LVOReplyMsg
xref _LVOAutoRequest
Start:
moveq.l #0,d6 ;zero no. viruses found
moveq.l #0,d5 ;zero no. disks installed
moveq.l #0,d4 ;zero no. disks checked
movem.l a0/d0,-(sp) ;save command line
move.l 4,a6
moveq.l #33,d0 ;version 33 or greater
lea Arp(pc),a1
jsr _LVOOpenLibrary(a6) ;open arp.library
tst.l d0
bne.s 1$
add.w #8,sp
move.l #20,d0 ;no library, indicate error and stop
rts
1$ move.l d0,a5 ;arpbase for later
movem.l (sp)+,a0/d0 ;get command line back
lea Help(pc),a1
lea CheckDisks(pc),a2
lea TPlate(pc),a3
exg a5,a6
jsr _LVOGADS(a6) ;parse command line
move.l #100,d0
jsr _LVOArpAlloc(a6) ;allocate 100 bytes of memory
exg a5,a6 ;for formatting strings
tst.l d0
beq Error
move.l d0,Mem1
sub.l a1,a1
jsr _LVOFindTask(a6) ;get our task
move.l d0,Task ;save for later
move.l d0,a1
move.l #19,d0
jsr _LVOSetTaskPri(a6);set our task to priorty 19
move.l d0,OldPri ;save old priority
moveq.l #0,d0
move.l d0,a0
exg a5,a6
jsr _LVOCreatePort(a6);create a reply port
exg a5,a6
tst.l d0
beq Error
move.l d0,d3
move.l d0,Port ;save for closing later
move.l #IOSTD_SIZE,d0
exg a6,a5
jsr _LVOArpAlloc(a6) ;allocate some memory for IO block
exg a6,a5
tst.l d0
beq Error
move.l d0,a0
move.b #NT_MESSAGE,LN_TYPE(a0)
move.w #IOSTD_SIZE,MN_LENGTH(a0)
move.l d3,MN_REPLYPORT(a0)
move.l d0,DiskReq ;save IO block address
moveq.l #3,d3
Loop lea TrackName(pc),a0
move.l d3,d0
move.l DiskReq,a1
moveq.l #0,d1
jsr _LVOOpenDevice(a6);open up trackdisk.device
tst.l d0
bgt.s Cont
move.w #TD_CHANGENUM,IO_COMMAND(a1)
jsr _LVODoIO(a6) ;find out change count for all drives
move.l IO_ACTUAL(a1),d0
lea ChangeCount(pc),a0
move.l d3,d1
lsl.l #2,d1
add.l d1,a0
move.l d0,(a0) ;set current change count
jsr _LVOCloseDevice(a6)
Cont dbra d3,Loop ;do 4 drives
lea MyNewWindow(pc),a0
move.l IntuiBase(a5),a6 ;get cached intuitionbase from arp.library
jsr _LVOOpenWindow(a6);open up our window
move.l 4,a6 ;restore ExecBase
tst.l d0
beq Error
move.l d0,MyWindow ;save for later
move.l d0,a0
move.l wd_RPort(a0),d0 ;get window rastport, saves time later
move.l d0,RPort
move.l wd_UserPort(a0),d0
move.l d0,UserPort ;also get userport
move.l d0,a0
moveq.l #0,d0
move.b MP_SIGBIT(a0),d0 ;get this ports signal number
moveq.l #1,d1
lsl.l d0,d1 ;convert into a mask
move.l d1,Signal ;and save
move.l #1536,d0
move.l #MEMF_CHIP!MEMF_CLEAR,d1
exg a5,a6
jsr _LVOArpAllocMem(a6) ;allocate buffer for disk read
exg a5,a6
tst.l d0
beq Error
move.l d0,Buffer ;save for later
lea CheckDisks(pc),a0 ;get flag from command line
tst.l (a0) ;will we test the drives no
beq.s 3$
moveq.l #3,d3 ;yes
lea ChangeCount(pc),a0
4$ move.l (a0),d0
cmp.l #-1,d0 ;is current count -1
bne.s 11$
addq.w #4,a0 ;yes, then no drive here
bra.s 12$
11$ move.l #1000,(a0)+ ;otherwise set count to 1000
12$ dbra d3,4$ ;do all drives attached
bsr CheckBlock ;and check disks
3$ move.l RPort,a1 ;get our rast port
moveq.l #1,d0
move.l GfxBase(a5),a6 ;get graphics base from ARP
jsr _LVOSetAPen(a6)
moveq.l #0,d0
jsr _LVOSetBPen(a6)
moveq.l #RP_JAM2,d0
jsr _LVOSetDrMd(a6)
MainLoop: ;where the work is done
move.l 4,a6
lea FmtString(pc),a0
move.l d6,-(sp)
move.l d5,-(sp)
move.l d4,-(sp)
move.l sp,a1
lea Format1(pc),a2
move.l Mem1,a3
jsr _LVORawDoFmt(a6) ;format screen title string
add.w #12,sp
move.l IntuiBase(a5),a6 ;from ARP
move.l MyWindow,a0 ;pointer to window
moveq.l #-1,d0
move.l d0,a1 ;don't change window title
move.l Mem1,a2 ;change screen title only
jsr _LVOSetWindowTitles(a6)
move.l 4,a6
Lp move.l UserPort,a0
jsr _LVOGetMsg(a6) ;see if any messages at our port
tst.l d0
bne.s Act
move.l Signal,d0 ;no then we will wait for one
jsr _LVOWait(a6)
bra.s Lp
Act move.l d0,a1 ;yes, lets see what it is
move.l im_Class(a1),d3 ;copy class
jsr _LVOReplyMsg(a6) ;reply to these fast
cmp.l #CLOSEWINDOW,d3 ;shall we close down
beq.s EndofLoop
cmp.l #DISKINSERTED,d3 ;or has someone put a disk in
bne.s MainLoop ;no, well thats all we want
bsr.s CheckBlock ;yes lets check it out
bra.s MainLoop
EndofLoop:
move.l Task,a0
move.l OldPri,d0
jsr _LVOSetTaskPri(a6) ;restore old priority
move.l IntuiBase(a5),a6
move.l MyWindow,a0
jsr _LVOCloseWindow(a6) ;close our window
exg a5,a6
move.l Port,a1
jsr _LVODeletePort(a6) ;delete our port
moveq.l #0,d0
jsr _LVOArpExit(a6) ;indicate a clean return
;arp doesn't come back from here
CheckBlock:
bsr WhoChanged ;find out which drive is involved
cmp.l #-1,d0 ;no more drives to check
beq Return
move.b d0,Unit ;save drive number
addq.l #1,d4 ;add one to number checked
lea TrackName(pc),a0
move.l DiskReq,a1
moveq.l #0,d1
jsr _LVOOpenDevice(a6) ;open trackdisk on unit
tst.l d0
bgt.s CheckBlock ;won't open, try next drive
move.l DiskReq,a1
move.w #CMD_READ,IO_COMMAND(a1)
move.l Buffer,d0
move.l d0,IO_DATA(a1)
move.l #1536,IO_LENGTH(a1)
move.l #0,IO_OFFSET(a1)
jsr _LVODoIO(a6) ;read boot block into buffer
move.l DiskReq,a1
move.w #TD_MOTOR,IO_COMMAND(a1)
move.l #0,IO_LENGTH(a1)
jsr _LVODoIO(a6) ;turn motor off
move.l DiskReq,a1
move.b IO_ERROR(a1),d3 ;see what error there was
jsr _LVOCloseDevice(a6)
cmp.b #19,d3
bgt.s CheckBlock ;if an error try next drive
move.l #255,d1
moveq.l #0,d2
move.l Buffer,a0
1$ move.l d2,d3
move.l (a0)+,d0
add.l d0,d2
cmp.l d2,d3
ble.s 2$
addq.l #1,d2
2$ dbra d1,1$ ; compute checksum on block
tst.l d2 ;if not zero then this will not boot
bne Return ;not a booting disk
move.l Buffer,a1
add.w #12,a1
move.l (a1),d0
cmp.l #$41FAFFF2,d0 ;check for SCA virus
bne.s NextCheck
addq.l #1,d6 ;another SCA virus found
bra.s DisplaySCA ;display message
NextCheck:
move.l Buffer,a1
add.w #32,a1
move.l (a1),d0
cmp.l #'Band',d0 ;check for Byte Bandit virus
bne.s CheckBoot
addq.l #1,d6 ;found one
bra.s DisplayBYT ;display message
CheckBoot:
move.l Buffer,a1
addq.w #8,a1
lea BootBlock+8(pc),a2
moveq.l #10,d3
1$ move.l (a1)+,d0 ;otherwise see if the block is a
move.l (a2)+,d1 ;standard booting disk
cmp.l d0,d1
bne.s DisplayNstd ;it isn't, then display message
dbra d3,1$ ;okay it is, next disk
bra CheckBlock ;see it any more disks changed
DisplaySCA:
move.b Unit,d0
add.b #'0',d0 ;set unit number on message
lea TEXTPTR+23(pc),a0
move.b d0,(a0)
move.l MyWindow,a0
lea SCABody(pc),a1
lea Pos(pc),a2
lea Neg1(pc),a3
Disp2 moveq.l #0,d0
move.l d0,d1
move.l #340,d2
move.l #75,d3
move.l IntuiBase(a5),a6
jsr _LVOAutoRequest(a6) ;ask remove or ignore
move.l 4,a6
tst.l d0
beq.s Okay1 ;okay ignore it
bsr DoInstall ;otherwise get rid of it
Okay1 bra CheckBlock
DisplayBYT:
move.b Unit,d0
add.b #'0',d0
lea TEXTPTR+23(pc),a0
move.b d0,(a0)
move.l MyWindow,a0
lea BYTBody(pc),a1
lea Pos(pc),a2
lea Neg1(pc),a3
bra Disp2 ;same here but why use the same code twice
DisplayNstd:
lea NBCTEXT(pc),a0
add.w #23,a0
move.b Unit,d0
add.b #'0',d0
move.b d0,(a0)
move.l MyWindow,a0
lea Body1,a1
lea PosD(pc),a2
lea Neg1(pc),a3
moveq.l #0,d0
moveq.l #0,d1
move.l #320,d2
move.l #75,d3
move.l IntuiBase(a5),a6
jsr _LVOAutoRequest(a6); tell user of Non-Standard block
move.l 4,a6
tst.l d0
beq CheckBlock ;Ignore it go check next drive
exg a5,a6
lea FileName(pc),a0
move.l a0,d1
move.l #MODE_NEWFILE,d2
jsr _LVOOpen(a6) ;open up a console window
exg a5,a6
tst.l d0
beq Cont3 ;error open window goto next requester
move.l d0,File ;save for later
exg a5,a6
link a5,#-30 ;get some space for string
move.l sp,Buff
moveq.l #12,d2 ;12 lines
move.l Buffer,a2
5$ moveq.l #24,d3 ;of 24 characters
move.l Buff,a3 ;get our stack space
4$ moveq.l #0,d0
move.b (a2)+,d0
cmp.b #' ',d0 ;if < space print a '.'
blt.s 1$
cmp.b #'~',d0 'if > '~' print a '.'
ble.s 2$
1$ move.b #'.',(a3)+
bra.s 3$
2$ move.b d0,(a3)+
3$ move.l d0,-(sp)
move.l sp,a1
lea Fmt1(pc),a0
move.l File,d0
jsr _LVOFPrintf(a6) ;print out hex value of number
add.w #4,sp
dbra d3,4$
move.b #0,(a3)
move.l Buff,a1
move.l a1,-(sp)
move.l sp,a1
lea Fmt2(pc),a0
move.l File,d0
jsr _LVOFPrintf(a6) ;print out string of characters
add.w #4,sp
dbra d2,5$
unlk a5 ;return stack space
exg a5,a6
Cont3 lea NBCTEXT(pc),a0
add.w #23,a0
move.b Unit,d0
add.b #'0',d0
move.b d0,(a0)
move.l MyWindow,a0
lea Body1,a1
lea Pos(pc),a2
lea Neg1(pc),a3
moveq.l #0,d0
moveq.l #0,d1
move.l #320,d2
move.l #75,d3
move.l IntuiBase(a5),a6
jsr _LVOAutoRequest(a6) ;get more input from user
move.l 4,a6
move.l d0,-(sp)
exg a5,a6
move.l File,d1
jsr _LVOClose(a6) ;close console device
exg a5,a6
move.l (sp)+,d0
tst.l d0
beq CheckBlock
bsr.s DoInstall ;clear block if user wants to
bra CheckBlock ;any more to do
DoInstall:
move.l IntuiBase(a5),a6
move.l MyWindow,a0
lea REWBody(pc),a1
lea REWPos(pc),a2
lea REWNeg(pc),a3
moveq.l #0,d0
moveq.l #0,d1
move.l #320,d2
move.l #75,d3
jsr _LVOAutoRequest(a6) ;last warning
move.l 4,a6
tst.l d0
beq Return ;no, make up your mind
addq.l #1,d5 ;disks installed +1
move.l Buffer,a0
move.l #256,d3
moveq.l #0,d0
1$ move.l d0,(a0)+ ;zero buffer
dbra d3,1$
move.l Buffer,a0
lea BootBlock(pc),a1
moveq.l #12,d3
2$ move.l (a1)+,(a0)+ ;copy standard boot block to buffer
dbra d3,2$
lea TrackName(pc),a0
move.l DiskReq,a1
move.b Unit,d0
ext.w d0
ext.l d0
moveq.l #0,d1
jsr _LVOOpenDevice(a6) ;open correct drive
tst.l d0
bgt Return
4$ move.l DiskReq,a1
move.w #TD_PROTSTATUS,IO_COMMAND(a1)
jsr _LVODoIO(a6) ;check write protect tab
move.l DiskReq,a1
move.l IO_ACTUAL(a1),d0
tst.l d0
beq.s 3$
move.l IntuiBase(a5),a6
move.l MyWindow,a0
lea ERRBody(pc),a1
lea ERRPos(pc),a2
lea ERRNeg(pc),a3
moveq.l #0,d0
moveq.l #0,d1
move.l #320,d2
move.l #75,d3
jsr _LVOAutoRequest(a6) ;ask user to take protect off
move.l 4,a6
tst.l d0
bne.s 4$
move.l DiskReq,a1
jsr _LVOCloseDevice(a6) ;or ignore the block again
bra Return
3$ move.l DiskReq,a1
move.l #1024,IO_LENGTH(a1)
move.l Buffer,a0
move.l a0,IO_DATA(a1)
move.w #CMD_WRITE,IO_COMMAND(A1)
move.l #0,IO_OFFSET(A1)
jsr _LVODoIO(a6) ;write block out to disk
move.l DiskReq,a1
move.w #CMD_UPDATE,IO_COMMAND(A1)
jsr _LVODoIO(a6) ;flush data to disk
move.l DiskReq,a1
move.b IO_ERROR(a1),d3 ;get error condition
move.w #TD_MOTOR,IO_COMMAND(A1)
move.l #0,IO_LENGTH(a1)
jsr _LVODoIO(a6) ;turn off drive
move.l DiskReq,a1
jsr _LVOCloseDevice(a6) ;shut down device
cmp.b #19,d3
ble.s 5$
lea ErrorND(pc),a1 ;if error > 19 then nothing done
bra.s 6$
5$ lea Healed(pc),a1 ;otherwise it was healed
6$ move.l MyWindow,a0
moveq.l #-1,d0
move.l d0,a3
move.l IntuiBase(a5),a6
jsr _LVOSetWindowTitles(a6);set window title
move.l DosBase(a5),a6
moveq.l #100,d1
jsr _LVODelay(a6) ;delay for 2 seconds
move.l IntuiBase(a5),a6
move.l MyWindow,a0
lea TITLETEXT(pc),a1
moveq.l #-1,d0
move.l d0,a3
jsr _LVOSetWindowTitles(a6) ;restore window title
move.l 4,a6
Return:
rts
WhoChanged:
moveq.l #3,d3
Loop1 move.l d3,d0
lsl.l #2,d0
lea ChangeCount(pc),a0
add.l d0,a0
move.l (a0),d0
cmp.l #-1,d0
beq.s Cont2
lea TrackName(pc),a0
move.l d3,d0
lea DiskReq(pc),a1
move.l (a1),a1
moveq.l #0,d1
jsr _LVOOpenDevice(a6)
tst.l d0
bgt.s Cont2
lea DiskReq(pc),a1
move.l (a1),a1
move.w #TD_CHANGESTATE,IO_COMMAND(a1)
jsr _LVODoIO(a6)
lea DiskReq(pc),a1
move.l (a1),a1
tst.l IO_ACTUAL(a1)
bne.s Cont1
move.w #TD_CHANGENUM,IO_COMMAND(a1)
jsr _LVODoIO(a6)
lea DiskReq(pc),a1
move.l (a1),a1
lea ChangeCount(pc),a2
move.l d3,d0
lsl.l #2,d0
add.l d0,a2
move.l IO_ACTUAL(a1),d0
move.l (a2),d1
cmp.l d0,d1
beq.s Cont1
move.l d0,(a2)
jsr _LVOCloseDevice(a6)
move.l d3,d0
rts
Cont1 jsr _LVOCloseDevice(a6)
Cont2 dbra d3,Loop1
move.l #-1,d0 ;return noone changed
rts
Error:
exg a5,a6
moveq.l #20,d0 ;indicate error
moveq.l #103,d1 ;indicate not enough memory error
jsr _LVOArpExit(a6)
;arp doesn't come back from here
Format1 move.b d0,(a3)+ ;this is used by _LVORawDoFmt
rts
ChangeCount dc.l $ffffffff
dc.l $ffffffff
dc.l $ffffffff
dc.l $ffffffff
File dc.l 0
Buff dc.l 0
Port dc.l 0
Signal dc.l 0
UserPort dc.l 0
Mem1 dc.l 0
Buffer dc.l 0
RPort dc.l 0
MyWindow dc.l 0
DiskReq dc.l 0
Task dc.l 0
OldPri dc.l 0
CheckDisks dc.l 0
MyNewWindow dc.w 128,0,300,10
dc.b 0,1
dc.l DISKINSERTED!CLOSEWINDOW!VANILLAKEY!MOUSEBUTTONS
dc.l WINDOWDRAG!WINDOWDEPTH!RMBTRAP!WINDOWCLOSE!NOCAREREFRESH
dc.l 0,0,TITLETEXT,0,0
dc.w 0,0,0,0,WBENCHSCREEN
Unit dc.b 0
dc.b 0
BootBlock dc.b 'DOS',0,$c0,$20,$0f,$19,0,0,3,$70,$43,$fa,0,$18
dc.b $4e,$ae,$ff,$a0,$4a,$80,$67,$0a,$20,$40,$20,$68
dc.b 0,$16,$70,0,$4e,$75,$70,$ff,$60,$fa,$64
dc.b $6f,$73,$2e,$6c,$69,$62,$72,$61,$72,$79,0,0,0,0,0
TITLETEXT dc.b 'Virus Checker:',0
Help dc.b 'CHECK = Check drives on Startup',0
TPlate dc.b 'CHECK/S',0
Fmt1 dc.b '%02lx',0
Fmt2 dc.b ' %s',10,0
FmtString dc.b 'Virus Checker: Disks Checked: %ld Disks Installed %ld Viruses Found: %ld',0
FileName dc.b 'CON:0/70/640/130/Hex Dump',0
Arp dc.b 'arp.library',0
TrackName dc.b 'trackdisk.device',0
NonStd dc.b 'Nonstandard Boot Code!',0
Display dc.b 'Display It',0
Ignore dc.b 'Ignore It',0
Remove dc.b 'Remove It',0
Retry dc.b 'Retry',0
Yes dc.b 'Yes',0
No dc.b 'No',0
Cancel dc.b 'Cancel',0
SCAV dc.b 'infected with an SCA Virus!!',0
BYTV dc.b 'infected with the Byte Bandit Virus!',0
WrtPro dc.b 'Write Protected.',0
DiskERR dc.b 'DISK ERROR: Disk is',0
Bootsec dc.b 'Rewrite the boot sectors?',0
Rewrite dc.b 'Are you sure you want to',0
NBCTEXT dc.b 'Danger: The disk in DF9: has',0
TEXTPTR dc.b 'Danger: The disk in DF9: is',0
ErrorND dc.b 'Error, Nothing Done.',0
Healed dc.b 'Disk Healed.',0
def_font dc.b 'topaz.font',0
cnop 0,2
TxtAt_Plain dc.l def_font
dc.w 8
dc.b FS_NORMAL,FPF_ROMFONT
Body2 dc.b 0,1,RP_JAM2,0
dc.w 20,18
dc.l TxtAt_Plain
dc.l NonStd
dc.l 0
Body1 dc.b 0,1,RP_JAM2,0
dc.w 20,8
dc.l TxtAt_Plain
dc.l NBCTEXT
dc.l Body2
PosD dc.b 0,1,RP_JAM2,0
dc.w 7,3
dc.l TxtAt_Plain
dc.l Display
dc.l 0
Neg1 dc.b 0,1,RP_JAM2,0
dc.w 7,3
dc.l TxtAt_Plain
dc.l Ignore
dc.l 0
Pos dc.b 0,1,RP_JAM2,0
dc.w 7,3
dc.l TxtAt_Plain
dc.l Remove
dc.l 0
SCABody2 dc.b 0,1,RP_JAM2,0
dc.w 20,18
dc.l TxtAt_Plain
dc.l SCAV
dc.l 0
SCABody dc.b 0,1,RP_JAM2,0
dc.w 20,8
dc.l TxtAt_Plain
dc.l TEXTPTR
dc.l SCABody2
BYTBody2 dc.b 0,1,RP_JAM2,0
dc.w 20,18
dc.l TxtAt_Plain
dc.l BYTV
dc.l 0
BYTBody dc.b 0,1,RP_JAM2,0
dc.w 20,8
dc.l TxtAt_Plain
dc.l TEXTPTR
dc.l BYTBody2
ERRBody2 dc.b 0,1,RP_JAM2,0
dc.w 20,18
dc.l TxtAt_Plain
dc.l WrtPro
dc.l 0
ERRBody dc.b 0,1,RP_JAM2,0
dc.w 20,8
dc.l TxtAt_Plain
dc.l DiskERR
dc.l ERRBody2
ERRPos dc.b 0,1,RP_JAM2,0
dc.w 7,3
dc.l TxtAt_Plain
dc.l Retry
dc.l 0
ERRNeg dc.b 0,1,RP_JAM2,0
dc.w 7,3
dc.l TxtAt_Plain
dc.l Cancel
dc.l 0
REWBody2 dc.b 0,1,RP_JAM2,0
dc.w 20,18
dc.l TxtAt_Plain
dc.l Bootsec
dc.l 0
REWBody dc.b 0,1,RP_JAM2,0
dc.w 20,8
dc.l TxtAt_Plain
dc.l Rewrite
dc.l REWBody2
REWPos dc.b 0,1,RP_JAM2,0
dc.w 7,3
dc.l TxtAt_Plain
dc.l Yes
dc.l 0
REWNeg dc.b 0,1,RP_JAM2,0
dc.w 7,3
dc.l TxtAt_Plain
dc.l No
dc.l 0
end